<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Other Libraries in the Distribution
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora076.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora078.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Other Libraries in the Distribution</H2>
The other libraries provided with the Objective CAML language distribution
relate to the following extensions:
<UL>
<LI>
<B>graphics</B>, with the portable <TT>Graphics</TT> module
that was described in chapter <A HREF="index.html#chap-PG">5</A>;

<LI><B>exact math</B>, containing many modules, and allowing
the use of exact calculations on integers and rational numbers.
Numbers are represented using Objective CAML integers whenever possible;

<LI><B>regular expression filtering</B>, allowing easier string and text 
manipulations. The <TT>Str</TT> module will be described in chapter
<A HREF="index.html#chap-AlexS">11</A>; 

<LI><B>Unix</B><B> system calls</B>, with the <TT>Unix</TT> module allowing
one to make unix system calls from Objective CAML. A large part of this
library is nevertheless compatible with Windows.
This bibliography will be used in chapters
<A HREF="index.html#chap-PS">18</A> and <A HREF="index.html#chap-PD">20</A>; 

<LI><B>light-weight processes</B>, comprising many modules that will
largely be described and used in chapter <A HREF="index.html#chap-PC">19</A>;

<LI><B>access to NDBD databases</B>, works only in Unix
and will not be described; 

<LI><B>dynamic loading of bytecode</B>, implemented by the
<TT>Dynlink</TT> module. 
</UL>
We will describe the big integer and dynamic loading
libraries by using them.<BR>
<BR>
<A NAME="toc108"></A>
<H3> Exact Math</H3>
<A NAME="sec-Num"></A>
<A NAME="@fonctions311"></A>
<A NAME="@concepts166"></A>
The big numbers library provides exact math functions using integers
and rational numbers. Values of type <I>int</I> and
<I>float</I> have two limitations: calculations on integers
are done <I>modulo</I> the greatest positive integer, which can
cause unperceived overflow errors; the results of floating point
calculations are rounded, which by propagation can lead to errors.
The library presented here mitigates these defects.<BR>
<BR>
This library is written partly in C. For this reason, you have to
build an interactive loop that includes this code using the command:
<PRE>
ocamlmktop -custom -o top nums.cma -cclib -lnums
</PRE>The library contains many modules. The two most important ones
are <TT>Num</TT> for all the operations and
<TT>Arith_status</TT> for controlling calculation options.
The general type <I>num</I> is a variant type gathering three
basic types: 
<A NAME="@fonctions312"></A>
<A NAME="@fonctions313"></A>
<A NAME="@fonctions314"></A>


<PRE><BR><B>type</B><CODE> </CODE>num<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Int<CODE> </CODE><B>of</B><CODE> </CODE>int<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Big_int<CODE> </CODE><B>of</B><CODE> </CODE>big_int<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Ratio<CODE> </CODE><B>of</B><CODE> </CODE>ratio<BR>

</PRE>

The types <I>big_int</I> and <I>ratio</I> are abstract.<BR>
<BR>
The operations on values of type <I>num</I> are followed by the symbol
<CODE>/</CODE>. For example the addition of two <I>num</I> variables is written
<TT>+/</TT> and will be of type <I>num -&gt; num -&gt; num</I>. It will be the
same for comparisons. Here is the first example that calculates the
factorial: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>fact_num<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE>&lt;=/</CODE><TT>)</TT><CODE> </CODE>n<CODE> </CODE><CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE> </CODE><CODE>*/</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>n<CODE> </CODE><CODE> </CODE><TT>(</TT>fact_num<CODE> </CODE><TT>(</TT><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE>-/</CODE><TT>)</TT><CODE> </CODE>n<CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><TT>)</TT>;;<BR><CODE>val fact_num : Num.num -&gt; Num.num = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>fact_num<CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><TT>)</TT>;;<BR><CODE>val r : Num.num = Num.Big_int &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Num.string_of_num<CODE> </CODE>r<CODE> </CODE><B>in</B><CODE> </CODE><TT>(</TT>String.sub<CODE> </CODE>n<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"..."</CODE><CODE> </CODE>;;<BR><CODE>- : string = "93326215443944152681699238856266700490715968264381..."</CODE><BR>

</PRE>
<BR>
<BR>
Opening the <TT>Num</TT> module makes the code of <TT>fact_num</TT>
easier to read:


<PRE><BR># <B>open</B><CODE> </CODE>Num<CODE> </CODE>;;<BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>fact_num<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><CODE> </CODE>n<CODE> </CODE><CODE>&lt;=/</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Int<CODE> </CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE>n<CODE> </CODE><CODE>*/</CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>fact_num<CODE> </CODE><TT>(</TT><CODE> </CODE>n<CODE> </CODE><CODE>-/</CODE><CODE> </CODE><TT>(</TT>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val fact_num : Num.num -&gt; Num.num = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Calculations using rational numbers are also exact. If we want to
calculate the number <I>e</I> by following the following definition:
<DIV ALIGN=center><TABLE CELLSPACING=0 CELLPADDING=0>
<TR VALIGN=middle><TD NOWRAP>
<I>e</I> = <I>lim</I></TD>
<TD NOWRAP><TABLE CELLSPACING=0 CELLPADDING=0>
<TR><TD>&nbsp;</TD>
</TR>
<TR><TD NOWRAP><FONT SIZE=2><I>m</I> -&gt; <FONT FACE=symbol>�</FONT></FONT></TD>
</TR></TABLE></TD>
<TD NOWRAP> </TD>
<TD NOWRAP><FONT FACE=symbol>
�<BR>�<BR>�<BR>�</FONT></TD>
<TD NOWRAP> 1 + </TD>
<TD NOWRAP><TABLE CELLSPACING=0 CELLPADDING=0>
<TR><TD NOWRAP ALIGN=center>1</TD>
</TR>
<TR><TD><HR NOSHADE SIZE=2></TD>
</TR>
<TR><TD NOWRAP ALIGN=center><I>m</I></TD>
</TR></TABLE></TD>
<TD NOWRAP> </TD>
<TD NOWRAP><FONT FACE=symbol>
�<BR>�<BR>�<BR>�</FONT></TD>
<TD NOWRAP><TABLE CELLSPACING=0 CELLPADDING=0>
<TR><TD ALIGN=left NOWRAP><FONT SIZE=2><I>m</I></FONT></TD>
</TR>
<TR><TD ALIGN=left><BR><BR><BR></TD>
</TR>
<TR><TD ALIGN=left NOWRAP><FONT SIZE=2>&nbsp;</FONT></TD>
</TR></TABLE></TD>
</TR></TABLE></DIV>
We should write a function that calculates this limit up to a certain <I>m</I>.


<PRE><BR># <B>let</B><CODE> </CODE><CODE> </CODE>calc_e<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE>+/</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><TT>(</TT><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE>//</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>m<TT>)</TT><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Num<CODE>.</CODE><TT>(</TT><CODE> </CODE><CODE>**/</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>a<CODE> </CODE><CODE> </CODE>m;;<BR><CODE>val calc_e : Num.num -&gt; Num.num = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>calc_e<CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><TT>)</TT>;;<BR><CODE>val r : Num.num = Ratio &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Num.string_of_num<CODE> </CODE>r<CODE> </CODE><B>in</B><CODE> </CODE><TT>(</TT>String.sub<CODE> </CODE>n<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>5</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"..."</CODE><CODE> </CODE>;;<BR><CODE>- : string = "27048138294215260932671947108075308336779383827810..."</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions315"></A>The <TT>Arith_status</TT> module allows us to control some
calculations such as the normalization of rational numbers,
approximation for printing, and processing null denominators. The
<TT>arith_status</TT> function prints the state of these indicators.


<PRE><BR># Arith_status.arith_status();;<BR><BR><CODE>Normalization during computation --&gt; OFF</CODE><BR><CODE>     (returned by get_normalize_ratio ())</CODE><BR><CODE>     (modifiable with set_normalize_ratio &lt;your choice&gt;)</CODE><BR><BR><CODE>Normalization when printing --&gt; ON</CODE><BR><CODE>     (returned by get_normalize_ratio_when_printing ())</CODE><BR><CODE>     (modifiable with set_normalize_ratio_when_printing &lt;your choice&gt;)</CODE><BR><BR><CODE>Floating point approximation when printing rational numbers --&gt; OFF</CODE><BR><CODE>     (returned by get_approx_printing ())</CODE><BR><CODE>     (modifiable with set_approx_printing &lt;your choice&gt;)</CODE><BR><BR><CODE>Error when a rational denominator is null --&gt; ON</CODE><BR><CODE>     (returned by get_error_when_null_denominator ())</CODE><BR><CODE>     (modifiable with set_error_when_null_denominator &lt;your choice&gt;)</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
 <BR>
<BR>
They can be modified according to the needs of a calculation.
For example, if we want to print an approximate value for a rational
number, we can obtain, for the preceding calculation:


<PRE><BR># Arith_status.set_approx_printing<CODE> </CODE><B>true</B>;;<BR><CODE>- : unit = ()</CODE><BR># Num.string_of_num<CODE> </CODE><TT>(</TT>calc_e<CODE> </CODE><TT>(</TT>Num<CODE>.</CODE>Int<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><TT>)</TT><TT>)</TT>;;<BR><CODE>- : string = "0.270481382942e1"</CODE><BR>

</PRE>
<BR>
<BR>
Calculations with big numbers take longer than those with integers
and the values occupy more memory. Nevertheless,
this library tries to use the most economical representations whenever
possible. In any event, the ability to avoid the propagation of
rounding errors and to do calculations on big numbers
justifies the loss of efficiency.<BR>
<BR>
<A NAME="toc109"></A>
<H3> Dynamic Loading of Code</H3>
<A NAME="sec-mod-dynlink"></A>
<A NAME="@fonctions316"></A>
<A NAME="@concepts167"></A>
<A NAME="@concepts168"></A>
The <TT>Dynlink</TT> module offers the ability to dynamically
load programs in the form of bytecode. The dynamic loading of
code provides the following advantages:
<UL>
<LI>
 reduces the size of a program's code. If certain modules are
not used, they are not loaded.

<LI> allows the choice at execution time of which module to load.
According to certain conditions at execution time you choose to load one
module rather than another.

<LI> allows the modification of the behavior of a module during execution.
Here again, under some conditions the program can load a
new module and hide the old code.
</UL>The interactive loop of Objective CAML already uses such a mechanism. It is
convenient to let the programmer have access to it as well.<BR>
<BR>
During the loading of an object file (with the <TT>.cmo</TT> extension),
the various expressions are evaluated. The main program, that initiated
the dynamic loading of the code does not have access to the names
of declarations. Therefore it is up to the dynamically loaded module
to update a table of functions used by the main program.<BR>
<BR>


<H3> Warning </H3> <HR>

The dynamic loading of code only works for object files in bytecode.


<HR>

<BR>
<BR>

<H4> Description of the Module</H4>
For dynamic loading of a bytecode file <TT>f.cmo</TT>, we need to know the
access path to the file and the names of the modules
that it uses.
By default, dynamically loaded bytecode files do not have access
to the paths and modules of the libraries in the distribution.
Thus we have to add the path and the name of the required modules to
the dynamic loading of the module.
<A NAME="@fonctions317"></A>
<A NAME="@fonctions318"></A>
<A NAME="@fonctions319"></A>
<A NAME="@fonctions320"></A>
<A NAME="@fonctions321"></A>
<A NAME="@fonctions322"></A>
<A NAME="@fonctions323"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>init</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>unit -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>initialize dynamic loading</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>add_interfaces</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>string list -&gt; string list -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>add the names of modules and paths 
 for loading</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>loadfile</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>string -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>load a bytecode file</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>clear_avalaible_units</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>unit -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>empty the names of loadable modules 
 and paths</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>add_avalaible_units</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>(string * Digest.t) list -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>add the name of a module and a checksum for
 loading without needing the interface file</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>allow_unsafe_modules</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>bool -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>allow the loading of files
 containing <B>external</B> declarations</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP><TT>loadfile_private</TT></TD>
<TD  VALIGN=top ALIGN=center NOWRAP>:</TD>
<TD  VALIGN=top ALIGN=left><I>string -&gt; unit</I></TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>the loaded module is not accessible 
 to modules loaded later</TD>
</TR>
<TR><TD  VALIGN=top ALIGN=left COLSPAN=3><FONT SIZE=2> The checksum of an interface </FONT><FONT SIZE=2><TT>.cmi</TT></FONT><FONT SIZE=2>
can be obtained from the </FONT><FONT SIZE=2><TT>extract_crc</TT></FONT><FONT SIZE=2> command found in the catalog
of libraries in the distribution.</FONT></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.10: Functions of the <TT>Dynlink</TT> module.</DIV><BR>

<A NAME="fig-mod-dynlink"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE><A NAME="@fonctions324"></A>
Many errors can occur during a request to load a module.
Not only must the file exist with the right interface
in one of the paths, but the bytecode must also be correct
and loadable. These errors are gathered in the type <I>error</I>
used as an argument to the <TT>Error</TT> exception and to the
<TT>error</TT> function of type <I>error -&gt; string</I> that
allows the conversion of an error into a clear description.<BR>
<BR>

<H4> Example</H4>
To write a small program that allows us to illustrate dynamic loading
of bytecode, we provide three modules:
<UL>
<LI>
 <TT>F</TT> that contains the definition of a reference to a function
<TT>f</TT>;

<LI> <TT>Mod1</TT> and <TT>Mod2</TT> that modify in different ways the
function referenced by <TT>F.f</TT>.
</UL>The <TT>F</TT> module is defined in the file <TT>f.ml</TT>:


<PRE><BR><B>let</B><CODE> </CODE>g<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"I am the 'f' function by default\n"</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE><CODE> </CODE>;;<BR><B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>g<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
The <TT>Mod1</TT> module is defined in the file <TT>mod1.ml</TT>:


<PRE><BR>print_string<CODE> </CODE><CODE>"The 'Mod1' module modifies the value of 'F.f'\n"</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><B>let</B><CODE> </CODE>g<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"I am the 'f' function of module 'Mod1'\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>F.f<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>g<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
The <TT>Mod2</TT> module is defined in the file <TT>mod2.ml</TT>:


<PRE><BR>print_string<CODE> </CODE><CODE>"The 'Mod2' module modifies the value of 'F.f'\n"</CODE><CODE> </CODE>;<CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR><B>let</B><CODE> </CODE>g<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"I am the 'f' function of module 'Mod2'\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE>flush<CODE> </CODE>stdout<CODE> </CODE>;;<BR>F.f<CODE> </CODE><CODE>:=</CODE><CODE> </CODE>g<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
Finally we define in the file <TT>main.ml</TT>, a main program
that calls the original function referenced by <TT>F.f</TT>, loads
the <TT>Mod1</TT> module, calls <TT>F.f</TT> again,
then loads the <TT>Mod2</TT> module and calls the <TT>F.f</TT> function
one last time:


<PRE><BR><B>let</B><CODE> </CODE>main<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Dynlink.init<CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Dynlink.add_interfaces<CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>"Pervasives"</CODE>;<CODE> </CODE><CODE>"F"</CODE><CODE> </CODE>;<CODE> </CODE><CODE>"Mod1"</CODE><CODE> </CODE>;<CODE> </CODE><CODE>"Mod2"</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE>Sys.getcwd()<CODE> </CODE>;<CODE> </CODE><CODE>"/usr/local/lib/ocaml/"</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>!</CODE><TT>(</TT>F.f<TT>)</TT><CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Dynlink.loadfile<CODE> </CODE><CODE>"mod1.cmo"</CODE><CODE> </CODE>;<CODE> </CODE><CODE> </CODE><CODE>!</CODE><TT>(</TT>F.f<TT>)</TT><CODE> </CODE>()<CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Dynlink.loadfile<CODE> </CODE><CODE>"mod2.cmo"</CODE><CODE> </CODE>;<CODE> </CODE><CODE> </CODE><CODE>!</CODE><TT>(</TT>F.f<TT>)</TT><CODE> </CODE>()<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Dynlink<CODE>.</CODE>Error<CODE> </CODE>e<CODE> </CODE>-&gt;<CODE> </CODE>print_endline<CODE> </CODE><TT>(</TT>Dynlink.error_message<CODE> </CODE>e<TT>)</TT><CODE> </CODE>;<CODE> </CODE>exit<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><BR>main<CODE> </CODE>()<CODE> </CODE>;;<BR>

</PRE>

The main program must, in addition to initializing the dynamic
loading, declare by a call to <TT>Dynlink.add_interfaces</TT>
the interface used.<BR>
<BR>
We compile all of these modules:
<PRE>
$ ocamlc -c f.ml
$ ocamlc -o main dynlink.cma f.cmo main.ml
$ ocamlc -c f.cmo mod1.ml
$ ocamlc -c f.cmo mod2.ml
</PRE>If we execute program <TT>main</TT>, we obtain:
<PRE>
$ main
I am the 'f' function by default
The 'Mod1' module modifies the value of 'F.f'
I am the 'f' function of module 'Mod1'
The 'Mod2' module modifies the value of 'F.f'
I am the 'f' function of module 'Mod2'
</PRE>Upon the dynamic loading of a module, its code is executed. This is
demonstrated in our example, with the outputs beginning with 
<TT>The 'Mod...</TT>. 
The possible side effects that it contains are therefore reflected
at the level of the program that caused the code to be loaded.
This is why the different calls to <TT>F.f</TT> call different functions.<BR>
<BR>
The <TT>Dynlink</TT> library offers the basic mechanism for dynamically
loading bytecode. The programmer still has to manage
tables such that the loading will really be effective.<BR>
<BR>
<BR>
<BR>

<BR>
<BR>
<HR>
<A HREF="book-ora076.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora078.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
